package org.example.curriculum_design_6_16.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.curriculum_design_6_16.config.SocialServiceConfig;
import org.example.curriculum_design_6_16.entity.pojo.SocialService;
import org.example.curriculum_design_6_16.entity.pojo.SocialServiceRule;
import org.example.curriculum_design_6_16.enums.SocialServiceGrade;
import org.example.curriculum_design_6_16.mapper.AttendanceAbsenceMapper;
import org.example.curriculum_design_6_16.mapper.SocialServiceRuleMapper;
import org.example.curriculum_design_6_16.service.AttendanceAbsenceService;
import org.example.curriculum_design_6_16.service.SocialServiceRuleService;
import org.example.curriculum_design_6_16.service.SocialServiceService;
import org.example.curriculum_design_6_16.mapper.SocialServiceMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 社会服务Service实现类
 * @author 郑凯
 * @description 针对表【social_service】的数据库操作Service实现
 * @createDate 2025-06-16 09:26:01
 */
@Service
public class SocialServiceServiceImpl extends ServiceImpl<SocialServiceMapper, SocialService>
    implements SocialServiceService{

    @Autowired
    private SocialServiceMapper socialServiceMapper;

    @Autowired
    private SocialServiceRuleMapper socialServiceRuleMapper;

    @Autowired
    private AttendanceAbsenceMapper attendanceAbsenceMapper;

    @Autowired
    private SocialServiceRuleService socialServiceRuleService;

    @Autowired
    private AttendanceAbsenceService attendanceAbsenceService;

    private Map<String, Double> getRules() {
        //得到有效规则
        List<SocialServiceRule> rules = socialServiceRuleMapper.findAllActiveRules();
        //使用Map映射服务规则对得分的映射
        Map<String, Double> ruleMap = new HashMap<>();

        for (SocialServiceRule rule : rules) {
            if (rule.getIsActive() == null) {
                continue;
            }
            if (rule.getRuleKey() != null && rule.getScoreValue() != null) {
                ruleMap.put(rule.getRuleKey(), rule.getScoreValue().doubleValue());
            }
        }
        return ruleMap;
    }

    @Override
    public int insertSocialService(SocialService socialService) {
        // 设置默认状态为已通过
        if (socialService.getStatus() == null) {
            socialService.setStatus(SocialService.STATUS_APPROVED);
        }
        if (socialService.getReviewComment() == null) {
            socialService.setReviewComment("自动通过");
        }
        
        // 1. 获取服务类型对应的基础分数
        Map<String, Double> rules = getRules();
        Double baseScore = rules.get(socialService.getServiceType());

        // 2. 计算持续时间（天数）
        Double durationDays = (double) calculateDurationDays(
                socialService.getStartDate(),
                socialService.getEndDate()
        );

        // 3. 计算最终得分（示例：基础分 × 持续时间系数）
        double finalScore = calculateFinalScore(baseScore, durationDays);

        // 4. 设置分数和持续时间
        socialService.setScore(rules.get(socialService.getServiceType()));
        socialService.setDuration(durationDays);

        // 5. 保存到数据库
        return socialServiceMapper.insert(socialService);
    }

    // 计算持续天数
    private long calculateDurationDays(Date startDate, Date endDate) {
        if (startDate == null || endDate == null) {
            return 0;
        }
        long diffInMillis = endDate.getTime() - startDate.getTime();
        return TimeUnit.DAYS.convert(diffInMillis, TimeUnit.MILLISECONDS) + 1; // 包含首尾两天
    }

    // 计算最终得分（根据业务规则调整）
    private double calculateFinalScore(double baseScore, Double durationDays) {
        // 示例规则：每月按30天计算，不足一月按比例
        double durationMonths = durationDays / 30.0;
        return baseScore * Math.min(durationMonths, 1.0); // 最多不超过基础分
    }

    /**
     * 校验服务类型是否合法（只认英文key）
     * 如有历史数据type为position/activity/other，需先批量UPDATE为标准key
     */
    public void validateServiceType(String serviceType) {
        Map<String, Double> rules = getRules();
        if (!StringUtils.hasText(serviceType) || !rules.containsKey(serviceType)) {
            throw new IllegalArgumentException("服务类型不合法！");
        }
    }

    /**
     * 计算单条记录的分数
     */
    @Override
    public double calculateSingleRecordScore(SocialService record, int rule8BeforeCount) {
        String serviceType = record.getServiceType();
        Double duration = record.getDuration() != null ? record.getDuration() : 0.0;

        // 从数据库获取规则
        SocialServiceRule rule = socialServiceRuleMapper.findByRuleKey(serviceType);
        if (rule == null || rule.getIsActive() == 0) {
            return 0.0;
        }

        // 检查最大次数限制
        if (rule.getMaxTimes() != null) {
            int currentCount = socialServiceMapper.countStudentServiceType(record.getStudentId(), serviceType);
            if (currentCount >= rule.getMaxTimes()) {
                return 0.0;
            }
        }

        double score = 0.0;

        // 处理需要时长的规则（主要是职位类）
        if (rule.getDurationRequired() == SocialServiceConfig.DURATION_REQUIRED_YES) {
            score = calculatePositionScore(rule, duration);
        }
        // 处理不需要时长的规则
        else {
            score = calculateActivityScore(rule, serviceType, rule8BeforeCount);
        }

        return score;
    }

    /**
     * 计算职位类分数
     */
    private double calculatePositionScore(SocialServiceRule rule, Double duration) {
        if (duration == null || duration <= 0) {
            return 0.0;
        }

        double baseScore = rule.getScoreValue().doubleValue();
        return SocialServiceConfig.calculatePositionScore(baseScore, duration);
    }

    /**
     * 计算活动类分数
     */
    private double calculateActivityScore(SocialServiceRule rule, String serviceType, int rule8BeforeCount) {
        double score = rule.getScoreValue().doubleValue();

        // 特殊处理规则8（志愿服务/考察实践）
        if (SocialServiceRule.RULE_KEY_VOLUNTEER_SERVICE.equals(serviceType) || 
            SocialServiceRule.RULE_KEY_INSPECTION_PRACTICE.equals(serviceType)) {
            // 每人0.2分，不叠加
            if (rule8BeforeCount > 0) {
                return 0.0;
            }
            return SocialServiceConfig.VOLUNTEER_SERVICE_SCORE;
        }

        // 其他活动类规则直接返回配置的分数
        return score;
    }

    /**
     * 计算并更新社会服务分数
     */
    @Override
    @Transactional
    public void calculateAndUpdateScores(String studentId, String academicYear) {
        List<SocialService> records = socialServiceMapper.findByStudentIdAndYear(studentId, academicYear);
        if (records == null || records.isEmpty()) {
            return;
        }

        // 只处理已通过审核的记录
        List<SocialService> approvedRecords = records.stream()
                .filter(record -> SocialService.STATUS_APPROVED.equals(record.getStatus()))
                .collect(Collectors.toList());

        if (approvedRecords.isEmpty()) {
            return;
        }

        // 统计规则8之前的记录数
        int rule8BeforeCount = socialServiceMapper.countRule8BeforeYear(studentId, academicYear);

        for (SocialService record : approvedRecords) {
            double score = calculateSingleRecordScore(record, rule8BeforeCount);
            socialServiceMapper.updateScore(record.getId(), score);
        }
    }

    /**
     * 计算基础分（15分减去缺勤扣分）
     */
    @Override
    public double calculateBaseScore(String studentId, String academicYear) {
        int absenceCount = attendanceAbsenceMapper.countUnapprovedAbsences(studentId, academicYear);
        double baseScore = SocialServiceConfig.BASE_SCORE_MAX - (absenceCount * SocialServiceConfig.ABSENCE_PENALTY);
        return SocialServiceConfig.ensureNonNegative(baseScore);
    }

    /**
     * 计算社会服务附加分（只认serviceType为英文key）
     * position_name、activity_name等中文字段仅用于展示，不参与分数逻辑
     * 如有历史数据type为position/activity/other，需先批量UPDATE为标准key
     */
    @Override
    public double calculateAdditionalScore(String studentId, String academicYear) {
        List<SocialService> records = socialServiceMapper.findByStudentIdAndYear(studentId, academicYear);
        if (records == null || records.isEmpty()) {
            return 0.0;
        }
        List<SocialService> approvedRecords = records.stream()
                .filter(record -> SocialService.STATUS_APPROVED.equals(record.getStatus()))
                .collect(Collectors.toList());
        double totalExtra = 0.0;
        Map<String, Double> rules = getRules();
        for (SocialService record : approvedRecords) {
            String type = record.getServiceType();
            if (rules.containsKey(type)) {
                totalExtra += rules.get(type);
            }
        }
        return Math.min(totalExtra, 5);
    }

    public int countActivity(String studentId, String academicYear) {
        return socialServiceMapper.countActivity(studentId, academicYear);
    }

    /**
     * 计算社会服务总分（基础分+附加分，上限20分）
     */
    @Override
    public double calculateTotalSocialScore(String studentId, String academicYear) {
        double baseScore = calculateBaseScore(studentId, academicYear);
        double additionalScore = calculateAdditionalScore(studentId, academicYear);
        return SocialServiceConfig.limitScore(baseScore + additionalScore, SocialServiceConfig.TOTAL_SCORE_MAX);
    }

    /**
     * 评定社会服务等级
     */
    @Override
    public String evaluateGrade(double totalScore) {
        return SocialServiceGrade.getGradeDescription(totalScore);
    }

    /**
     * 获取学生的社会服务等级
     */
    @Override
    public String getStudentGrade(String studentId, String academicYear) {
        double totalScore = calculateTotalSocialScore(studentId, academicYear);
        return evaluateGrade(totalScore);
    }

    /**
     * 批量计算学生社会服务分数
     */
    @Override
    @Transactional
    public void batchCalculateScores(List<String> studentIds, String academicYear) {
        for (String studentId : studentIds) {
            calculateAndUpdateScores(studentId, academicYear);
        }
    }

    /**
     * 获取学生的社会服务统计信息
     */
    @Override
    public Map<String, Object> getStudentStatistics(String studentId, String academicYear) {
        Map<String, Object> statistics = new HashMap<>();
        
        // 基础信息
        statistics.put("studentId", studentId);
        statistics.put("academicYear", academicYear);
        
        // 分数信息
        double baseScore = calculateBaseScore(studentId, academicYear);
        double additionalScore = calculateAdditionalScore(studentId, academicYear);
        double totalScore = calculateTotalSocialScore(studentId, academicYear);
        String grade = evaluateGrade(totalScore);
        
        statistics.put("baseScore", baseScore);
        statistics.put("additionalScore", additionalScore);
        statistics.put("totalScore", totalScore);
        statistics.put("grade", grade);
        
        // 记录统计
        List<Map<String, Object>> recordStats = socialServiceMapper.getStudentStatistics(studentId, academicYear);
        statistics.put("recordStatistics", recordStats);
        
        // 记录列表
        List<SocialService> records = socialServiceMapper.findApprovedRecords(studentId, academicYear);
        statistics.put("records", records);
        
        return statistics;
    }

    /**
     * 审核社会服务记录
     */
    @Override
    @Transactional
    public void reviewRecord(Integer recordId, Integer status, String comment) {
        socialServiceMapper.updateStatus(recordId, status, comment);
        
        // 如果审核通过，重新计算该学生的分数
        if (SocialService.STATUS_APPROVED.equals(status)) {
            SocialService record = socialServiceMapper.selectById(recordId);
            if (record != null) {
                calculateAndUpdateScores(record.getStudentId(), record.getAcademicYear());
            }
        }
    }

    /**
     * 获取待审核的记录
     */
    @Override
    public List<SocialService> getPendingRecords() {
        return socialServiceMapper.findPendingRecords();
    }

    /**
     * 验证社会服务记录是否符合规则
     */
    @Override
    public Map<String, Object> validateRecord(SocialService record) {
        Map<String, Object> result = new HashMap<>();
        List<String> errors = new ArrayList<>();
        
        // 基本验证
        if (record.getStudentId() == null || record.getStudentId().trim().isEmpty()) {
            errors.add("学生ID不能为空");
        }
        
        if (record.getServiceType() == null || record.getServiceType().trim().isEmpty()) {
            errors.add("服务类型不能为空");
        }
        
        if (record.getAcademicYear() == null || record.getAcademicYear().trim().isEmpty()) {
            errors.add("学年不能为空");
        }
        
        // 规则验证
        if (record.getServiceType() != null) {
            SocialServiceRule rule = socialServiceRuleMapper.findByRuleKey(record.getServiceType());
            if (rule == null) {
                errors.add("无效的服务类型");
            } else if (rule.getIsActive() == SocialServiceConfig.ACTIVE_NO) {
                errors.add("该服务类型规则已禁用");
            } else {
                // 检查最大次数限制
                if (rule.getMaxTimes() != null) {
                    int currentCount = socialServiceMapper.countStudentServiceType(record.getStudentId(), record.getServiceType());
                    if (currentCount >= rule.getMaxTimes()) {
                        errors.add("已达到该服务类型的最大次数限制");
                    }
                }
                
                // 特殊验证：志愿服务和考察实践需要证明材料
                if ((SocialServiceRule.RULE_KEY_VOLUNTEER_SERVICE.equals(record.getServiceType()) || 
                     SocialServiceRule.RULE_KEY_INSPECTION_PRACTICE.equals(record.getServiceType())) &&
                    (record.getProofUrl() == null || record.getProofUrl().trim().isEmpty())) {
                    errors.add("志愿服务和考察实践活动需要提供当地党政部门出具的证明");
                }
            }
        }
        
        result.put("valid", errors.isEmpty());
        result.put("errors", errors);
        
        return result;
    }

    /**
     * 获取社会服务规则映射
     */
    @Override
    public Map<String, SocialServiceRule> getRuleMap() {
        List<SocialServiceRule> rules = socialServiceRuleMapper.findAllActiveRules();
        return rules.stream()
                .collect(Collectors.toMap(SocialServiceRule::getRuleKey, rule -> rule));
    }

    // 在新增和更新社会服务记录时调用校验方法
    @Override
    public boolean save(SocialService entity) {
        // 设置默认状态为已通过
        if (entity.getStatus() == null) {
            entity.setStatus(SocialService.STATUS_APPROVED);
        }
        if (entity.getReviewComment() == null) {
            entity.setReviewComment("自动通过");
        }
        validateServiceType(entity.getServiceType());
        return super.save(entity);
    }

    @Override
    public boolean updateById(SocialService entity) {
        // 设置默认状态为已通过
        if (entity.getStatus() == null) {
            entity.setStatus(SocialService.STATUS_APPROVED);
        }
        if (entity.getReviewComment() == null) {
            entity.setReviewComment("自动通过");
        }
        validateServiceType(entity.getServiceType());
        return super.updateById(entity);
    }
}




